﻿using System;
using System.Web;
using System.Net.Mail;
using System.Configuration;

using GG.Data;
namespace GG.Mail
{
    public class MyMailManager
    {
        #region Private Variable
        private MailMessage mail = null;
        private MailAddress mailAddress = null;
        private SmtpClient mailClient = null;
        private int clientPort = -1;
        private string clientHost = String.Empty;
        private bool isEnabledSsl = false;
        private int mailType = -1;
        private string mailBody = "";
        private MailPriority mailPriority = MailPriority.Normal;

        static string smtphost = System.Configuration.ConfigurationSettings.AppSettings["smtphost"].ToString();// "smtp.gmail.com";
        static string smtpport = System.Configuration.ConfigurationSettings.AppSettings["smtpport"].ToString();//"465";
        static string smtpaccount = System.Configuration.ConfigurationSettings.AppSettings["smtpaccount"].ToString();//"comparexpress.submissions@gmail.com";
        static string smtpauthcode = System.Configuration.ConfigurationSettings.AppSettings["smtpauthcode"].ToString();//"sg2010express";
        static bool smtpenablessl = true;

        #endregion

        public MyMailManager()
        {
            mailClient = new SmtpClient();
            mailClient.Host = "smtp.gmail.com";
            mailClient.Port = 465;
            mailClient.EnableSsl = true;
        }

        public MyMailManager(string HostName, string Port, bool EnableSSL, string Account, string AuthCode)
        {
            smtphost = HostName;
            smtpenablessl = EnableSSL;
            smtpport = Port;
            smtpaccount = Account;
            smtpauthcode = AuthCode;
        }

        public static bool SendEmail(string EmailTitle, string mailBody, string ToEmailAddress, string CCEmailAddress, string BCCEmailAddress)
        {
            string smtphost = ConfigurationManager.AppSettings["smtphost"].ToString();
            string smtpport = ConfigurationManager.AppSettings["smtpport"].ToString();
            string smtpaccount = ConfigurationManager.AppSettings["smtpaccount"].ToString();
            string smtpauthcode = ConfigurationManager.AppSettings["smtpauthcode"].ToString();
            string smtpdisplayname = ConfigurationManager.AppSettings["smtpdisplayname"].ToString();
            bool smtpenablessl = Convert.ToBoolean(ConfigurationManager.AppSettings["smtpenablessl"].ToString());

            string islive = ConfigurationManager.AppSettings["islive"].ToString();
            if (islive == "0")
            {
                EmailTitle = "[TS] " + EmailTitle;
            }
            bool _result = SendMailNew(smtphost,
                        Convert.ToInt32(smtpport),
                        smtpaccount,
                        smtpauthcode,
                        smtpdisplayname,
                        smtpaccount,
                        "CX Admin",
                        ToEmailAddress,
                        CCEmailAddress,
                        BCCEmailAddress,
                        EmailTitle,
                        mailBody,
                        smtpenablessl);
            return _result;
        }

        public static bool SendEmailWithAttach(string EmailTitle, string mailBody, string ToEmailAddress, string CCEmailAddress, string BCCEmailAddress, string[] fileList)
        {
            string smtphost = ConfigurationManager.AppSettings["smtphost"].ToString();
            string smtpport = ConfigurationManager.AppSettings["smtpport"].ToString();
            string smtpaccount = ConfigurationManager.AppSettings["smtpaccount"].ToString();
            string smtpauthcode = ConfigurationManager.AppSettings["smtpauthcode"].ToString();
            string smtpdisplayname = ConfigurationManager.AppSettings["smtpdisplayname"].ToString();
            bool smtpenablessl = Convert.ToBoolean(ConfigurationManager.AppSettings["smtpenablessl"].ToString());
            
            string islive = ConfigurationManager.AppSettings["islive"].ToString();
            if (islive == "0")
            {
                EmailTitle = "[TS] " + EmailTitle;
            }

            bool _result = SendMailNewByAttachments(smtphost,
                        Convert.ToInt32(smtpport),
                        smtpaccount,
                        smtpauthcode,
                        smtpdisplayname,
                        smtpaccount,
                        "CX Admin",
                        ToEmailAddress,
                        CCEmailAddress,
                        BCCEmailAddress,
                        EmailTitle,
                        mailBody,
                        smtpenablessl, fileList);
            return _result;
        }

        public static bool SendMailNew(string sHost, int nPort, string sUserName, string sPassword, string sFromName, string sFromEmail,
        string sToName, string sToEmail, string sCCEmail, string sBCCEmail, string sHeader, string sMessage, bool fSSL)
        {
            if (sToName.Length == 0)
                sToName = sToEmail;
            if (sFromName.Length == 0)
                sFromName = sFromEmail;

            try
            {
                MailMessage Mail = new MailMessage();

                if (sToEmail != "")
                {
                    string[] sGetToEmails = sToEmail.Split(';');

                    foreach (string toemail in sGetToEmails)
                    {
                        if (toemail != "")
                            Mail.To.Add(new MailAddress(toemail));
                    }
                }

                if (sCCEmail != "")
                {
                    string[] sGetCCEmails = sCCEmail.Split(';');

                    foreach (string ccemail in sGetCCEmails)
                    {
                        if (ccemail != "")
                            Mail.CC.Add(new MailAddress(ccemail));
                    }
                }

                if (sBCCEmail != "")
                {
                    string[] sGetBCCEmails = sBCCEmail.Split(';');

                    foreach (string bccemail in sGetBCCEmails)
                    {
                        if (bccemail != "")
                            Mail.Bcc.Add(new MailAddress(bccemail));
                    }

                }

                Mail.From = new MailAddress(sFromEmail, sFromName); ;
                Mail.Subject = sHeader;
                Mail.Body = sMessage;
                Mail.IsBodyHtml = true;

                SmtpClient smtp = new SmtpClient();
                smtp.Timeout = 300000;
                smtp.Port = nPort;
                smtp.Host = sHost;
                smtp.Credentials = new System.Net.NetworkCredential(sUserName, sPassword);

                if (fSSL)
                {
                    smtp.EnableSsl = true;
                }

                object userState = Mail;

                smtp.SendCompleted += new SendCompletedEventHandler(MailDeliveryComplete);
                smtp.Send(Mail);
            }
            catch(Exception Ex)
            {
                string _emailSetting = "Host : " + sHost + " From Email : " + sUserName + " To Email : " + sToEmail + " Subject : " + sHeader;
                CreateExceptionLog(Ex, _emailSetting, "SendMailNew Exception");

                return false;
            }
            finally
            {
                if (ConfigurationManager.AppSettings["MailCountActive"].ToString() == "1")
                {
                    MyData _myData = new MyData();
                    _myData.InsertMailCountLog("GG Service - Call List");
                }
            }
            return true;
        }

        public static bool SendMailNewByAttachments(string sHost, int nPort, string sUserName, string sPassword, string sFromName, string sFromEmail,
        string sToName, string sToEmail, string sCCEmail, string sBCCEmail, string sHeader, string sMessage, bool fSSL, string[] fileList)
        {
            if (sToName.Length == 0)
                sToName = sToEmail;
            if (sFromName.Length == 0)
                sFromName = sFromEmail;

            try
            {
                MailMessage Mail = new MailMessage();

                if (sToEmail != "")
                {
                    string[] sGetToEmails = sToEmail.Split(';');

                    foreach (string toemail in sGetToEmails)
                    {
                        if (toemail != "")
                            Mail.To.Add(new MailAddress(toemail));
                    }
                }

                if (sCCEmail != "")
                {
                    string[] sGetCCEmails = sCCEmail.Split(';');

                    foreach (string ccemail in sGetCCEmails)
                    {
                        if (ccemail != "")
                            Mail.CC.Add(new MailAddress(ccemail));
                    }
                }

                if (sBCCEmail != "")
                {
                    string[] sGetBCCEmails = sBCCEmail.Split(';');

                    foreach (string bccemail in sGetBCCEmails)
                    {
                        if (bccemail != "")
                            Mail.Bcc.Add(new MailAddress(bccemail));
                    }

                }

                Mail.From = new MailAddress(sFromEmail, sFromName);
                Mail.Subject = sHeader;
                Mail.Body = sMessage;
                Mail.IsBodyHtml = true;

                SmtpClient smtp = new SmtpClient();
                smtp.Timeout = 300000;
                smtp.Port = nPort;
                smtp.Host = sHost;
                smtp.Credentials = new System.Net.NetworkCredential(sUserName, sPassword);

                if (fSSL)
                {
                    smtp.EnableSsl = true;
                }

                object userState = Mail;

                for (int i = 0; i < fileList.Length; i++)
                {
                    Mail.Attachments.Add(new Attachment(fileList[i].ToString()));

                    //An Int32 that specifies the time-out value in milliseconds. 
                    //The default value is 100,000 (100 seconds).
                    smtp.Timeout += 240000;
                }

                smtp.SendCompleted += new SendCompletedEventHandler(MailDeliveryComplete);
                smtp.Send(Mail);
            }
            catch (Exception Ex)
            {
                string _emailSetting = "Host : " + sHost + " From Email : " + sUserName + " To Email : " + sToEmail + " Subject : " + sHeader;
                CreateExceptionLog(Ex, _emailSetting, "SendMailNew By Attachments Exception");

                return false;
            }
            finally
            {
                if (ConfigurationManager.AppSettings["MailCountActive"].ToString() == "1")
                {
                    MyData _myData = new MyData();
                    _myData.InsertMailCountLog("GG Service - Call List");
                }
            }
            return true;
        }

        static void MailDeliveryComplete(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            //Console.WriteLine("Message \"{0}\".", e.UserState);

            if (e.Error != null)
            {
                try
                {
                    //Get the Original MailMessage object
                    MailMessage mail = (MailMessage)e.UserState;

                    //write out the subject
                    string subject = mail.Subject;

                    System.Text.StringBuilder errorMsg = new System.Text.StringBuilder();
                    errorMsg.Append(string.Format("An error occurred sending message [{0}]. {1}", e.UserState.ToString(), e.Error.Message));

                    if (e.Error.InnerException != null)
                        errorMsg.Append(Environment.NewLine + "Inner exception message: " + e.Error.InnerException.Message);

                    errorMsg.Append(Environment.NewLine + "Subject: " + subject);
                    errorMsg.Append(Environment.NewLine + "Sender: " + mail.Sender.Address.ToString());
                    errorMsg.Append(Environment.NewLine + "Sender Host: " + mail.Sender.Host.ToString());
                    errorMsg.Append(Environment.NewLine + "From : " + mail.From.Address.ToString());
                    errorMsg.Append(Environment.NewLine + "From Host : " + mail.From.Host.ToString());
                    string _toAddresses = "";
                    foreach (MailAddress _msgMail in mail.To)
                    {
                        _toAddresses += _msgMail.Address.ToString() + ";";
                    }
                    errorMsg.Append(Environment.NewLine + "To : " + _toAddresses);
                    CreateMailDeliveryExceptionLog("SendMailNew MailDeliveryComplete Exception", errorMsg);
                }
                catch (Exception Ex)
                {
                    Ex = null;
                }
            }
            else if (e.Cancelled)
            {
                //Console.WriteLine("Sending of email cancelled.");
            }
            else
            {
                //Console.WriteLine("Message sent.");
            }
        }

        private static void CreateMailDeliveryExceptionLog(string strLocation, System.Text.StringBuilder ErrorMessage)
        {
            String[] _fileContent = new String[3];
            _fileContent[0] = "Date Time : " + GG.Global.General.GetUTCDateTime().ToString();
            _fileContent[1] = "Location : " + "MyMailManager - " + strLocation;
            _fileContent[2] = "Message : " + ErrorMessage;

            WriteMailDeliveryExceptionLog("MailDelivery_", _fileContent);
        }

        private static void WriteMailDeliveryExceptionLog(string strPrefixFileName, string[] strException)
        {
            try
            {
                GG.InputOut.MyIO _newFile = new GG.InputOut.MyIO();
                string _filePath = AppDomain.CurrentDomain.BaseDirectory + "Exception\\";
                if (_newFile.CheckDirectory(_filePath))
                {
                    string _curMonth = GG.Global.General.GetUTCDateTime().Year.ToString("0000") + GG.Global.General.GetUTCDateTime().Month.ToString("00");

                    if (!_newFile.CheckDirectory(_filePath + _curMonth))
                    {
                        if (_newFile.CreateDirectory(_filePath, _curMonth))
                        {
                            _filePath += _curMonth + "\\";
                        }
                    }
                    else
                    {
                        _filePath += _curMonth + "\\";
                    }

                    string _fileName = strPrefixFileName + _curMonth + GG.Global.General.GetUTCDateTime().Day.ToString("00") + GG.Global.General.GetUTCDateTime().Second.ToString("00") + GG.Global.General.GetUTCDateTime().Millisecond.ToString("00") + ".txt";

                    _newFile.WriteNewFile(_filePath, _fileName, strException);
                    _newFile = null;
                }
            }
            catch (Exception Ex)
            {
                Ex = null;
            }
        }

        private static void CreateExceptionLog(Exception Ex, string EmailSettingInfo, string strLocation)
        {
            String[] _fileContent = new String[7];
            _fileContent[0] = "Email Setting : " + EmailSettingInfo;
            _fileContent[1] = "Source : " + Ex.Source;
            _fileContent[2] = "Date Time : " + GG.Global.General.GetUTCDateTime().ToString();
            _fileContent[3] = "Stack Trace :" + Ex.StackTrace.ToString();
            _fileContent[4] = "Target Site : " + Ex.TargetSite.ToString();
            _fileContent[5] = "Location : " + "MyMailManager - " + strLocation;
            _fileContent[6] = "Message : " + Ex.Message;

            WriteExceptionLog("Mail_", _fileContent);
        }

        private static void WriteExceptionLog(string strPrefixFileName, string[] strException)
        {
            try
            {
                GG.InputOut.MyIO _newFile = new GG.InputOut.MyIO();
                string _filePath = AppDomain.CurrentDomain.BaseDirectory + "Exception\\";
                if (_newFile.CheckDirectory(_filePath))
                {
                    string _curMonth = GG.Global.General.GetUTCDateTime().Year.ToString("0000") + GG.Global.General.GetUTCDateTime().Month.ToString("00");

                    if (!_newFile.CheckDirectory(_filePath + _curMonth))
                    {
                        if (_newFile.CreateDirectory(_filePath, _curMonth))
                        {
                            _filePath += _curMonth + "\\";
                        }
                    }
                    else
                    {
                        _filePath += _curMonth + "\\";
                    }

                    string _fileName = strPrefixFileName + _curMonth + GG.Global.General.GetUTCDateTime().Day.ToString("00") + GG.Global.General.GetUTCDateTime().Second.ToString("00") + GG.Global.General.GetUTCDateTime().Millisecond.ToString("00") + ".txt";

                    _newFile.WriteNewFile(_filePath, _fileName, strException);
                    _newFile = null;
                }
            }
            catch (Exception Ex)
            {
                Ex = null;
            }
        }

    }
}
